package com.xiaoge.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * TODO
 *
 * @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>
 * @since
 */
@Controller
//@SessionAttributes("name")  // todo 它是把session中的key为name的, 加入到model中
public class ZhangXiaoController {

	@Autowired
	private ZhangXiaoController zhangXiaoController;

//	/**
//	 * 自定义参数解析器, 但是它只会对该类上的方法有效, 设置成全局的看 ZhangXiaoControllerAdvice
//	 * @param binder
//	 */
//	@InitBinder
//	public void initBinder(WebDataBinder binder) {
//		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//		simpleDateFormat.setLenient(false);
//		binder.registerCustomEditor(Date.class, new CustomDateEditor(simpleDateFormat, false));
//	}

	/**
	 * todo http://localhost:8080/app/a?date=2023-06-27&xxx=1,(注意每次请求必须加这个这个方法的参数) 当我们访问这个地址的时候它会先执行addString方法,
	 * 	然后把@ModelAttribute注解里面的值当做key, 返回值value当做value, 把它封装到test方法参数的model里面
	 *
	 * 	todo 当前addString是只在这个类上面有效, 全局的设置在ZhangXiaoControllerAdvice中, 因为它有@ControllerAdvice注解
	 * @param value
	 * @return
	 */
//	@ModelAttribute("user")
//	public String addString(@RequestParam("xxx") String value) {
//		return value;
//	}

	/**
	 * todo 因为我们类上面加了@SessionAttributes("name"), 我们访问test的时候, 它会把session中的值给test中的model对象
	 * @param request
	 * @return
	 */
	@GetMapping("/b1")
	@ResponseBody
	public String test1(HttpServletRequest request) {
		request.getSession().setAttribute("name", "zhangsan");
		return "success";
	}

	@GetMapping("/a1")
	@ResponseBody
	public String test2(Date date, HttpServletRequest request, Model model) {
		System.out.println(zhangXiaoController);
//		return (String) model.getAttribute("user");
		return (String) model.getAttribute("name");
	}

	@GetMapping("/a2")
	@ResponseBody
	public String test3(String name) {
		return name + "zhangsan";
	}

	@GetMapping("/a3")
	@ResponseBody
	public String test4(Date date) {
		return date + "zhangsan";
	}

	@GetMapping("/a4/{id}")
	@ResponseBody
	public String test5(@PathVariable("id") String id) {
		return id + "zhangsan";
	}

	@GetMapping("/a5")
	@ResponseBody
	public String test6(@RequestParam Map map) {
		return map + "zhangsan";
	}

	@GetMapping("/a6")
	@ResponseBody
	public Map test7(@RequestParam String name) {
		Map<Object, Object> map = new HashMap<>();
		map.put("name", name);
		return map;
	}

	@GetMapping("/a7")
	public String test8() {
		return "index";
	}

	/**
	 * todo 注意转发request共用, model不是共用的, 因为每次请求它都会创建一个新的modelAndView对象去初始化model等
	 * 		但是, 它会在渲染的时候把model中的属性会添加到request的attribute中
	 * @param request
	 * @param model
	 * @return
	 */
	@GetMapping("/a8")
	public String test9(HttpServletRequest request, Model model) {
		request.setAttribute("name", "zhangsan");
		request.setAttribute("name1", "zhangsan1");
		return "forward:/app/b2";
	}

	@GetMapping("/b2")
	@ResponseBody
	public String test10(HttpServletRequest request, Model model) {
		return (String) request.getAttribute("name1");

	}


	/**
	 * todo 注意重定向它会把model里面的值拼接到请求后面 http://xxx:xxx/xxx?key=value
	 * 		如果非要共享数据可以用flashMap底层是通过session
	 * @param request
	 * @param model
	 * @return
	 */
	@GetMapping("/a9")
	public String test11(HttpServletRequest request, Model model) {
		model.addAttribute("name", "zhangsan");
		model.addAttribute("name1", "zhangsan1");
		FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
		outputFlashMap.put("name2", "zhangsan2");
		return "redirect:/app/b3";
	}

	@GetMapping("/b3")
	@ResponseBody
	public String test12(HttpServletRequest request, Model model) {
		System.out.println(request.getAttribute("name"));
		System.out.println(request.getParameter("name"));
		System.out.println(request.getParameter("name2"));
		Map<String, ?> inputFlashMap = RequestContextUtils.getInputFlashMap(request);
		System.out.println(inputFlashMap.get("name2"));
		return "1";

	}
}
